<?php
/**
 * RedXenon Framework
 * 
 * LICENSE
 * 
 * This source file is subject to the New BSD license that is bundled
 * with this package in the file LICENSE.txt
 * A copy of this license can be found in the world-wide-web at this URL:
 * http://www.redxenon.com/license/new-bsd-license.txt
 */

/* Abstract Class */
require_once("RXQuery.php");

/** 
 * RedXenon Database (RXSelect.php)
 * Class to manage Database Select Queries
 * 
 * @category RedXenon
 * @package RedXenon_Database
 * @copyright Copyright (c) 2011 Red Xenon (http://www.redxenon.com)
 * @version $Id: RXSelect.php 1.0 2011-09-06 $ 
 */
class RXSelect extends RXQuery{
	
	private $order;
	private $limitFrom;
	private $limitLength;
	private $fields;
	private $isDistinct;
	private $result;
	
	/**
	 * Constructor
	 * @param RXDatabaseConnection $connection
	 * @param String $query
	 * @see RXQuery::__construct
	 */
	public function __construct($connection = NULL, $query = NULL){
		parent::__construct($connection, $query);
	}
	
	/**
	 * Destructor
	 * @see RXQuery::__destruct()
	 */
	public function __destruct(){
		if($this->result){
			$this->result->close();
		}
		parent::__destruct();
	}
	
	/**
	 * Sets the value for the limit where the query will take records
	 * @var $limit Integer 
	 */
	public function setLimitFrom($limit){
		$this->limitFrom = $limit;
	}
	
	/**
	 * Returns the limit value
	 * @return Integer
	 */
	public function getLimitFrom(){
		return $this->limitFrom;
	}
	
	/**
	 * Sets the value for the limit length
	 * @param Integer $length
	 */
	public function setLimitLength($length){
		$this->limitLength = $length;
	}
	
	/**
	 * Returns the limit length value
	 * @return Integer
	 */
	public function getLimitLength(){
		return $this->limitLength;
	}
	
	/**
	 * Sets the limit values
	 * @param Integer $length
	 * @param Integer $limitFrom
	 */
	public function setLimit($length, $limitFrom = NULL){
		self::setLimitLength($length);
		self::setLimitFrom($limitFrom);
	}
	
	/**
	 * Sets a field for the order statement
	 * @param String $field
	 * @param String $order
	 */
	public function addOrderField($field, $order = NULL){
		if($this->order){
			$this->order .= ", `".$field."`";
		}else{
			$this->order  = "ORDER BY `".$field."`";
		}
		
		if($order){
			$this->order .= " ".$order;
		}
	}
	
	/**
	 * Sets a string value to the order parameter
	 * @param String $order
	 */
	public function setOrder($order){
		if(preg_match('/ORDER BY/i', $order)){
			$this->order = $order;
		}else{
			$this->order = "ORDER BY ".$order;
		}
		$this->order = $order;
	}
	
	/**
	 * Returns the order statement
	 * @return String
	 */
	public function getOrder(){
		return $this->order;
	}
	
	public function addField($fieldName, $as = NULL, $tableName = NULL){
		if(!$this->fields || !is_array($this->fields)){
			$this->fields = array();
		}
		
		array_push($this->fields, array(	"fieldName" => $fieldName,
																"as" => $as, 
																"tableName" => $tableName 
													  ));													  
	}
	
	public function setDistinct(){
		$this->isDistinct = TRUE;
	}
	
	public function buildQuery(){			
		/* SELECT */
		$this->query = "SELECT ";
		
		/* DISTINCT */
		if($this->isDistinct){
			$this->query .= "DISTINCT ";
		}
		
		/* FIELDS */
		if(!$this->fields || !is_array($this->fields)){
			$this->query .= "*";
		}else{
			foreach($this->fields as $field){
				if($field["fieldName"]){
					if($field["tableName"]){
						$this->query .= $field["tableName"].".";
					}
					$this->query .= $field["fieldName"];
					if($field["as"]){
						$this->query .= " AS ".$field["as"];
					}
					$this->query .= ", ";
				}
			}
			$this->query = substr($this->query, 0, strlen($this->query) - 2);
		}
		
		/* FROM */
		$this->query .= " FROM ";
		if(is_array($this->tables)){
			foreach($this->tables as $table){
				$this->query .= $table["tableName"];
				if($table["as"]){
					$this->query .= " AS ".$table["as"];
				}
				$this->query .= ", ";
			}
			$this->query = substr($this->query, 0, strlen($this->query) - 2);
		}else{
			$this->query .= $this->tables;
		}
		
		/* WHERE */
		if($this->where){
			$this->query .= " WHERE ".$this->where;
		}
		
		if($this->order){
			$this->query .= " ".$this->order;
		}
		
		if($this->limitLength){
			$this->query .= " LIMIT ";
			if($this->limitFrom)
				$this->query .= $this->limitFrom.",".$this->limitLength;
			else 
				$this->query .= $this->limitLength;
		}
	}
	
	public function execute(){
		if(!$this->query){
			$this->buildQuery();
		}else{
			if($this->limitLength){
				$this->query .= " LIMIT ";
				if($this->limitFrom)
					$this->query .= $this->limitFrom.",".$this->limitLength;
				else 
					$this->query .= $this->limitLength;
			}
		}
					
		$this->result = parent::exec();
	}
	
	public function next($type = MYSQLI_BOTH){
		if($this->result){
			return $this->result->fetch_array($type);
		}else{
			return FALSE;
		}
	}
	
	public function count(){
		if($this->result){
			return $this->result->num_rows;
		}
	}
}

?>